package src;

/*
 * Created on Mar 7, 2005
 *
 * TODO To change the template for this generated file go to
 */


import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;

//import org.w3c.tools.codec.Base64Decoder;
//import org.w3c.tools.codec.Base64FormatException;

//import InternalServerErrorException;

public class Server2 {
	
	protected Hashtable headers = new Hashtable();
	protected String method = "";
	protected String httpVersion = "";
	protected String URI = "";
	protected byte[] body = new byte[0];
	protected boolean scriptRequest = false;
	protected String pathInfo = "";
	protected String queryString = "";
	
	public static String checkAuthentication(String authenticationString) {//throws InternalServerErrorException {
        StringTokenizer stringTokenizer = new StringTokenizer(authenticationString, " \t");
        String type = stringTokenizer.nextToken();
        
        Base64Decoder decoder = new Base64Decoder(stringTokenizer.nextToken());
        String namePassword;
        try {
            namePassword = decoder.processString();
        } catch (Base64FormatException e) {
            System.out.println("Incorrectly formatted authentication string: " + e);
            return null;
        }
        stringTokenizer = new StringTokenizer(namePassword, ":");
        String name = stringTokenizer.nextToken();
        
        String password = stringTokenizer.nextToken();
        try {
            BufferedReader authUserFileReader = new BufferedReader(new FileReader("user.txt"));
            String line = authUserFileReader.readLine();
            while (line != null) {
                if (line.length() == 0) {
                    line = authUserFileReader.readLine();
                    continue;
                }
                stringTokenizer = new StringTokenizer(line, ":");
                if (name.equals(stringTokenizer.nextToken())) {
                    decoder = new Base64Decoder(stringTokenizer.nextToken());
                    String tmp = decoder.processString();
                    if (password.equals(tmp)) {
                        return name;
                    } else {
                        return null;
                    }
                }
                line = authUserFileReader.readLine();
            }
            authUserFileReader.close();
        } catch (FileNotFoundException e) {
            System.err.println("Error opening AuthUserFile: " + e);
            //throw new InternalServerErrorException();
        } catch (IOException e) {
            System.err.println("Error reading AuthUserFile file: " + e);
            //throw new InternalServerErrorException();
        } catch (Base64FormatException e) {
            System.err.println("Incorrectly formatted password string: " + e);
            //throw new InternalServerErrorException();
        }
        return null;
    }
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ServerSocket ding = null; 
		Socket dong = null; 

		try { 
		// Read in "conf/httpd.conf" and make an object that handles all information about it 
		// HttpdConf, ReadHMsg are classes you have to implement. 
		// ServerSocket, Socket are availalbe Java classes. 
			ding = new ServerSocket(1247); 
			System.out.println("Opened socket " + 1247); 
			while (true) { 
				// keeps listening for new clients, one at a time 
				try { 
					dong = ding.accept(); // waits for client here 
				}
				catch (IOException e) { 
					System.out.println("Error opening socket"); 
					System.exit(1); 
				}
				
				int which = process(dong.getInputStream());
				
				FileOutputStream outLog = null;

			    BufferedOutputStream out = new BufferedOutputStream(dong.getOutputStream());  
			    //BufferedOutputStream out = new BufferedOutputStream(outLog);  
				PrintWriter writer = new PrintWriter(out,true);  // char output to the client
			    
			      // every response will always have the status-line, date, and server name\
				if(which == 2) {
				 writer.println("HTTP/1.1 403 Forbidden");
                 writer.println("Server: TEST");
                 writer.println("Connection: close");
                 //writer.println("WWW-Authenticate: Basic realm=\"Test\"");
                 writer.println("");
				}
				else if (which == 1) {
					 writer.println("HTTP/1.1 200 Okay");
	                 writer.println("Server: TEST");
	                 writer.println("Connection: close");
	                 writer.println("Content-type: text/html");
	                 writer.println("");
	                 writer.println("<html><body><h1>It works!!!!!</h1></body></html>");
				} else {
					writer.println("HTTP/1.1 401 Authorization Required");
	                 writer.println("Server: TEST");
	                 writer.println("Connection: close");
	                 writer.println("WWW-Authenticate: Basic realm=\"Test\"");
	                 writer.println("");
				}
   
                   System.out.println("Finished reading headers");
                   dong.close();
                 				
			}
		}
		catch (IOException e) { 
			System.out.println("Error opening socket"); 
			System.exit(1); 
		}
	}
	public static int process (InputStream stream) {
		
		BufferedReader in = new BufferedReader(new InputStreamReader(stream));
		try {
			// read the first line to get the request method, URI and HTTP version
			String line = in.readLine();
			//parseFirstLine(line);
			System.out.println(line);
		
			// read headers
			line = in.readLine();
			while (line != null && line.trim().length() > 0) {
		    
				int index = line.indexOf(": ");
				if (index > 0) {
					//headers.put(line.substring(0, index), line.substring(index + 2));
					System.out.println(line);
					if(line.contains("Authorization")) {
						String authenticationString = line.substring(index+1);
						String result = checkAuthentication(authenticationString);
						if(result == null)
							return 2;
						System.out.println("Athorization worked!! " + result);
						return 1;
					}
				} else {
					break;
				}
				line = in.readLine();
			}
		}
		catch (IOException e) {
			System.out.println("Error reading body"); 
			System.exit(1);
		} //InternalServerErrorException();
		/*catch (InternalServerErrorException e) {
			System.out.println("Error reading body"); 
			System.exit(1);
		} */
		return 0;
	}
		/*
		// read body
		String contentLength = (String)headers.get("Content-Length");
		
		if (contentLength != null) {
			try {

				int length = Integer.parseInt(contentLength.trim());
				body = new byte[length];
				int count = 0;
				
				while (count < length) {
					int byteRead = in.read();
					body[count++] = (byte)byteRead;
				}
			} catch (NumberFormatException e) {
				throw new InvalidRequestException("Invalid Content-Length - " + contentLength);
			}
		} 
		*/ 
		
}
	





